﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using ASPItalia.ModelVirtualCasting.Web.RiaServices;
using System.ComponentModel;
using ASPItalia.ModelVirtualCasting.Silverlight.Data;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Command;
using System.Collections;
using ASPItalia.ModelVirtualCasting.Silverlight.BackOffice.Views;
using System.Windows.Printing;
using System.Windows.Threading;
using System.Runtime.InteropServices.Automation;
using System.Reflection;
using System.IO;
using Uploader;
using Microsoft.Xna.Framework.Audio;
using System.Threading;
using Microsoft.Windows.Data.DomainServices;
using System.Windows.Data;
using ASPItalia.ModelVirtualCasting.Silverlight.BackOffice.Converters;

namespace ASPItalia.ModelVirtualCasting.Silverlight.BackOffice.ViewModels
{
    public class HomeViewModel : ViewModelBase
    {
        PrintDocument _doc;
        DataManager _data;
        public RelayCommand<IList> SelectionChangedCommand { get; private set; }
        public RelayCommand<People> ViewDetailsCommand { get; private set; }
        public RelayCommand FilterCommand { get; private set; }

        public HomeViewModel()
        {
            if (DesignerProperties.IsInDesignTool)
            {
            }
            else
            {
                _data = new DataManager();
            }

            SelectionChangedCommand = new RelayCommand<IList>(SelectedChanged);
            ViewDetailsCommand = new RelayCommand<People>(ViewDetails);
            FilterCommand = new RelayCommand(Filter);

            Messenger.Default.Register<MessageType>(this, ManageMessage);

            _peopleTypes = PeopleTypeCollection.Elements;
            _peopleTypesSource.Source = _peopleTypes;
            PeopleTypesView.Refresh();
        }

        private void ManageMessage(MessageType messageType)
        {
            switch (messageType)
            {
                case MessageType.Load:
                    LoadPeople();
                    break;
                case MessageType.Print:
                    Print();
                    break;
                case MessageType.Export:
                    Export();
                    break;
                case MessageType.Save:
                    SaveOnDisk();
                    break;
                default:
                    break;
            }
        }

        private ObservableCollection<People> _people = new ObservableCollection<People>();
        public ObservableCollection<People> People
        {
            get { return _people; }
            set
            {
                _people = value;
                RaisePropertyChanged("People");
            }
        }

        private ObservableCollection<PeopleType> _peopleTypes;
        private CollectionViewSource _peopleTypesSource = new CollectionViewSource();
        public ICollectionView PeopleTypesView
        {
            get
            {
                return _peopleTypesSource.View;
            }
        }

        string _stringSearch = string.Empty;
        public string StringSearch
        {
            get { return _stringSearch; }
            set
            {
                _stringSearch = value;
                RaisePropertyChanged("StringSearch");
            }
        }

        int _itemsCount = 0;
        public int ItemsCount
        {
            get { return _itemsCount; }
            set
            {
                _itemsCount = value;
                RaisePropertyChanged("ItemsCount");
            }
        }
        int _currentPage = 0;
        public int CurrentPage
        {
            get { return _currentPage; }
            set
            {
                _currentPage = value;
                RaisePropertyChanged("CurrentPage");
            }
        }

        Tuple<bool, string> _processing;
        public Tuple<bool, string> Processing
        {
            get { return _processing; }
            set
            {
                _processing = value;
                RaisePropertyChanged("Processing");

                Messenger.Default.Send<Tuple<bool, string>>(value);
            }
        }

        int _selectedItemsCount;
        public int SelectedItemsCount
        {
            get { return _selectedItemsCount; }
            set
            {
                _selectedItemsCount = value;
                RaisePropertyChanged("SelectedItemsCount");

                if (_selectedItemsCount > 2)
                {
                    var _soundStream = Application.GetResourceStream(new Uri("stereol.wav", UriKind.RelativeOrAbsolute));
                    var _effect = SoundEffect.FromStream(_soundStream.Stream);
                    SoundEffectInstance soundInstance = _effect.CreateInstance();
                    soundInstance.IsLooped = false;
                    soundInstance.Pitch = -1.0f;
                    soundInstance.Volume = 0.75f;
                    soundInstance.Play();
                }
            }
        }

        public void LoadPeople()
        {
            Processing = Tuple.Create<bool, string>(true, "caricamento in corso");

            _data.LoadPeople(
                new QueryBuilder<People>().OrderBy(p => p.LastName).Skip(CurrentPage * 5).Take(5),
                (ServiceLoadResult<People> result) =>
                {
                    if (result.Error != null)
                    {
                        ErrorWindow.CreateNew(result.Error.Message);
                        Processing = Tuple.Create<bool, string>(false, "errore");
                    }
                    else if (!result.Cancelled)
                    {
                        Processing = Tuple.Create<bool, string>(false, "completato");

                        People.Clear();
                        foreach (var item in result.Entities)
                            People.Add(item);
                    }
                }, null
            );
        }

        public void SelectedChanged(IList items)
        {
            SelectedItemsCount = items.Count;
            Messenger.Default.Send<IList>(items);
        }

        public void ViewDetails(People item)
        {
            PeopleDetails p = new PeopleDetails(item);
            p.Show();
        }

        private void Filter()
        {
            Processing = Tuple.Create<bool, string>(true, "caricamento in corso");
            Thread.Sleep(3000);

            QueryBuilder<People> qb = new QueryBuilder<People>().Where(p => p.LastName.StartsWith(StringSearch));

            if (PeopleTypesView.CurrentItem != null)
            {
                PeopleType pt = (PeopleType)PeopleTypesView.CurrentItem;
                qb.Where(p => p.Type.Equals(pt.Code, StringComparison.InvariantCultureIgnoreCase));
            }

            _data.LoadPeople(
                qb.OrderBy(p => p.LastName).Skip(CurrentPage * 5).Take(5),
                (ServiceLoadResult<People> result) =>
                {
                    if (result.Error != null)
                    {
                        ErrorWindow.CreateNew(result.Error.Message);
                        Processing = Tuple.Create<bool, string>(false, "errore");
                    }
                    else if (!result.Cancelled)
                    {
                        Processing = Tuple.Create<bool, string>(false, "completato");

                        People.Clear();
                        foreach (var item in result.Entities)
                            People.Add(item);
                    }
                }, null
            );
        }

        public void Print()
        {
            _doc = new PrintDocument();
            _doc.PrintPage += new EventHandler<PrintPageEventArgs>(doc_PrintPage);
            _doc.Print("documento");
        }
        void doc_PrintPage(object sender, PrintPageEventArgs e)
        {
            Size area = e.PrintableArea;

            //DataGrid _dg = new DataGrid();
            //_dg.ItemsSource = People;
            //_dg.Width = area.Width;
            //_dg.Height = area.Height * 2;

            string outData = string.Empty;
            TextBox _dg = new TextBox();

            foreach (People item in People)
            {
                outData += ASPItalia.ModelVirtualCasting.Silverlight.BackOffice.Manager.Helper.ObjectToString(item);
            }
            _dg.Text = outData;

            e.PageVisual = _dg;
        }

        public void Export()
        {
            dynamic excel = AutomationFactory.CreateObject("Excel.Application");
            excel.Visible = true;
            dynamic workbook = excel.workbooks;
            workbook.Add();
            dynamic sheet = excel.ActiveSheet;

            dynamic cell = null;

            int i = 1;
            foreach (People item in People)
            {

                Type type = item.GetType();
                PropertyInfo[] properties = type.GetProperties();
                foreach (PropertyInfo p in properties)
                {
                    try
                    {
                        if (p.GetValue(item, null) != null)
                        {
                            cell = sheet.Cells[i, 1];
                            cell.Value = p.Name;
                            cell.ColumnWidth = 25;
                            cell = sheet.Cells[i, 2];
                            cell.Value = p.GetValue(item, null);
                            i++;
                        }
                    }
                    catch (Exception)
                    {
                    }
                }

                i++;
            }
        }

        public void SaveOnDisk()
        {
            if (Application.Current.HasElevatedPermissions)
            {
                //accesso a tutto il file system
                DirectoryInfo dInfo = Directory.CreateDirectory(@"C:\RCD-test");

                string myDocuments = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                string filename = "test.txt";
                string path = System.IO.Path.Combine(myDocuments, filename);
                string outData = string.Empty;

                foreach (People item in People)
                {
                    outData += ASPItalia.ModelVirtualCasting.Silverlight.BackOffice.Manager.Helper.ObjectToString(item);
                }
                File.WriteAllText(path, outData);

                NotificationWindow tost = new NotificationWindow();
                tost.Content = new TextBlock() { Text = "Salvataggio completato" };
                tost.Height = 50;
                tost.Width = 200;
                tost.Show(1000);
            }

            if (App.Current.IsRunningOutOfBrowser)
            {
                new Window()
                {
                    Height = 400,
                    Width = 500,
                    Top = 24,
                    Left = 30,
                    Title = "Nuova Window",
                    Content = new LinkedText(),
                    Visibility = Visibility.Visible
                };

            }
        }
    }
}